Skip to content

feat(utils): add request context hash helper for trace correlation#237

Merged
Chucks1093 merged 1 commit into
accesslayerorg:mainfrom
Spagero763:feat/request-context-hash-209
Apr 27, 2026
Merged

feat(utils): add request context hash helper for trace correlation#237
Chucks1093 merged 1 commit into
accesslayerorg:mainfrom
Spagero763:feat/request-context-hash-209

Conversation

@Spagero763
Copy link
Copy Markdown
Contributor

@Spagero763 Spagero763 commented Apr 27, 2026

Summary

  • Adds computeRequestContextHash(req) in src/utils/request-context-hash.utils.ts that produces a stable 12-character hex digest from safe (non-sensitive) request fields: HTTP method, URL path (query string stripped), and content-type header (charset suffix stripped)
  • Applies the hash in requestLoggerMiddleware as a contextHash field on every log entry so log lines from the same endpoint/method share a stable tag for trace correlation
  • Adds a full Jest test suite (src/utils/test/request-context-hash.utils.test.ts) covering determinism, field sensitivity, query-string isolation, sensitive-header exclusion, and edge cases

What is NOT included

Authorization, Cookie, body, query string, and any other sensitive fields are deliberately excluded from the hash computation to avoid leaking user-supplied values into log aggregation.

Test plan

  • computeRequestContextHash returns 12-char lowercase hex
  • Same inputs → same hash (deterministic)
  • Different method / path / content-type → different hash
  • Query strings do not affect the hash
  • Authorization and Cookie headers do not affect the hash
  • content-type; charset=utf-8 treated same as content-type
  • Empty path falls back to /
  • Method comparison is case-insensitive

Closes #209

…ccesslayerorg#209)

Adds computeRequestContextHash() that hashes method, path, and
content-type into a stable 12-char hex digest for log correlation,
applied in requestLoggerMiddleware as contextHash field.

Closes accesslayerorg#209
Copilot AI review requested due to automatic review settings April 27, 2026 20:46
@drips-wave
Copy link
Copy Markdown

drips-wave Bot commented Apr 27, 2026

@Spagero763 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a deterministic, non-sensitive request “context hash” for correlating log lines across the same endpoint/method, and wires it into request logging.

Changes:

  • Introduces computeRequestContextHash(req) utility that hashes method + path (no query) + normalized content-type.
  • Adds contextHash to requestLoggerMiddleware log payloads.
  • Adds Jest tests covering determinism and normalization behavior.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
src/utils/request-context-hash.utils.ts New helper that computes a short SHA-256-derived context hash from safe request fields
src/middlewares/request-logger.middleware.ts Adds contextHash to request logs for correlation
src/utils/test/request-context-hash.utils.test.ts New Jest suite validating hashing behavior and normalization

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

*/
export function computeRequestContextHash(req: Request): string {
const path = (req.path || '/').split('?')[0];
const contentType = (req.headers['content-type'] ?? '').split(';')[0].trim();
Copy link

Copilot AI Apr 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

req.headers['content-type'] is typed as string | string[] | undefined (IncomingHttpHeaders). Calling .split() on it will either fail TypeScript compilation or throw at runtime if multiple content-type headers are present. Normalize to a single string first (e.g., Array.isArray(v) ? v[0] : v ?? '') before splitting/trim.

Suggested change
const contentType = (req.headers['content-type'] ?? '').split(';')[0].trim();
const rawContentType = req.headers['content-type'];
const normalizedContentType = Array.isArray(rawContentType)
? (rawContentType[0] ?? '')
: (rawContentType ?? '');
const contentType = normalizedContentType.split(';')[0].trim();

Copilot uses AI. Check for mistakes.
Comment on lines +4 to +10
function makeReq(overrides: Partial<{ method: string; path: string; headers: Record<string, string> }>): Request {
return {
method: 'GET',
path: '/',
headers: {},
...overrides,
} as unknown as Request;
Copy link

Copilot AI Apr 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The helper should handle content-type being a string[] (possible when duplicate headers are present), but the tests only cover the string case and the makeReq helper currently types headers as Record<string, string>, which makes it hard to add this coverage. Consider widening the header type (e.g., Record<string, string | string[]>) and adding a test asserting ['application/json; charset=utf-8'] behaves the same as 'application/json; charset=utf-8'.

Copilot uses AI. Check for mistakes.
@Chucks1093 Chucks1093 merged commit 26eabdf into accesslayerorg:main Apr 27, 2026
4 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add request context hash helper for trace correlation

3 participants